home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 6
/
FM Towns Free Software Collection 6.iso
/
t_os
/
chtiff
/
source
/
chtiff2.c
< prev
next >
Wrap
Text File
|
1993-07-08
|
7KB
|
274 lines
/*
TownsTIFF ←→ NeXTTIFF コンバーター
ファイル書き出し部分
*/
#include<stdio.h>
#include<stdlib.h>
#include"define.h"
#define WRITE_SECTION 1
#include"function.h"
/*
関数readdataの逆で書き込み用
同じくintel/Motorolaを吸収する。結局、書き込む値別に関数を作った。
*/
void write_BYTE(unsigned long offset, unsigned char data)
{
unsigned long backup_offset;
if(offset){
backup_offset=ftell(to.fp);
fseek(to.fp, offset, SEEK_SET);
}
fputc(data, to.fp);
if(offset) fseek(to.fp, backup_offset, SEEK_SET);
return;
}
void write_SHORT(unsigned long offset, unsigned short data)
{
unsigned long backup_offset;
if(offset){
backup_offset=ftell(to.fp);
fseek(to.fp, offset, SEEK_SET);
}
if(to.Intel){
fputc( (data & 0xff), to.fp);
fputc( (data >> 8) , to.fp);
}
else{
fputc( (data >>8) , to.fp);
fputc( (data & 0xff), to.fp);
}
if(offset) fseek(to.fp, backup_offset, SEEK_SET);
return;
}
void write_LONG(unsigned long offset, unsigned long data)
{
unsigned long backup_offset;
if(offset){
backup_offset=ftell(to.fp);
fseek(to.fp, offset, SEEK_SET);
}
if(to.Intel){
fputc( (data ) & 0xff, to.fp); /* 最下位8bit */
fputc( (data>> 8) & 0xff, to.fp);
fputc( (data>>16) & 0xff, to.fp);
fputc( (data>>24) , to.fp); /* 最上位8bit */
}
else{
fputc( (data>>24) , to.fp); /* 最上位8bit */
fputc( (data>>16) & 0xff, to.fp);
fputc( (data>> 8) & 0xff, to.fp);
fputc( (data ) & 0xff, to.fp); /* 最下位8bit */
}
if(offset) fseek(to.fp, backup_offset, SEEK_SET);
return;
}
/* エントリを一つ書き込む。 */
void write_entry(unsigned short tag, unsigned short type,
unsigned long len, unsigned long value)
{
write_SHORT(0UL,tag);
write_SHORT(0UL,type);
write_LONG (0UL,len);
switch(type){
case BYTE_TYPE:
if( len>4 ) goto LONG; /* 書き込む値が4バイト以上の時 */
write_BYTE(0UL, (unsigned char)value );
fputc(0, to.fp); fputc(0, to.fp); fputc(0, to.fp);
break;
case SHORT_TYPE:
if( len>2 ) goto LONG; /* 書き込む値が4バイト以上の時 */
write_SHORT(0UL, (unsigned short)value );
fputc(0, to.fp); fputc(0, to.fp);
break;
case LONG_TYPE: case RATIONAL_TYPE:
LONG:
write_LONG (0UL, value);
}
/* だらだらかき出すだけ・・・ */
}
/*
グローバル変数toにしたがってIFDをかき出す。
fpは予めセットされてること
*/
void write_IFD(void)
{
unsigned long Strip_Offset;
unsigned long Strips_ByteCount;
unsigned long X_Res;
unsigned long Y_Res;
unsigned long Color_Map;
unsigned long BPS_len;
unsigned long BPS_offset;
unsigned int i,j;
/* Resolution の書き込み */
X_Res=ftell(to.fp);
Y_Res=X_Res+8;
write_LONG(0UL,to.X_Resolution.bunsi);
write_LONG(0UL,to.X_Resolution.bunbo);
write_LONG(0UL,to.Y_Resolution.bunsi);
write_LONG(0UL,to.Y_Resolution.bunbo);
/* Strip_Offset & Strips_ByteCount の書き込み */
if(to.Strips!=1){
Strip_Offset = ftell(to.fp);
for(i=0; i<to.Strips; i++)
write_LONG(0UL, *(to.Strip_Offset + i) );
Strips_ByteCount = ftell(to.fp);
for(i=0; i<to.Strips; i++){
write_LONG(0UL, *(to.Strips_ByteCount + i) );
}
}
else{
Strip_Offset=*(to.Strip_Offset);
Strips_ByteCount=*(to.Strips_ByteCount);
}
/* Color_Map の書き込み */
if( to.Photo_Interp==3 ){
j = 1<<to.Bits_Per_Sample;
Color_Map=ftell(to.fp);
for(i=0; i<j; i++)
write_SHORT(0UL, *(to.RED +i) );
for(i=0; i<j; i++)
write_SHORT(0UL, *(to.GREEN+i) );
for(i=0; i<j; i++)
write_SHORT(0UL, *(to.BLUE +i) );
}
/* Bits Per Sample の24ビットの場合 */
if(to.Bits_Per_Sample == 24){
BPS_offset = ftell(to.fp);
write_SHORT(0UL, 8);
write_SHORT(0UL, 8);
write_SHORT(0UL, 8);
BPS_len = 3;
}
else{
BPS_len = 1;
}
/* IFD offset の書き込み。 */
write_LONG( 4UL, ftell(to.fp) );
/* IFD field entry の書き込み */
if(to.Photo_Interp == 3) write_SHORT(0UL,17);
else write_SHORT(0UL,16);
write_entry(0xfe , LONG_TYPE, 1UL, to.New_Subfile_Type);
write_entry(0x100, SHORT_TYPE, 1UL, UL_ to.Image_Width);
write_entry(0x101, SHORT_TYPE, 1UL, UL_ to.Image_Length);
if(BPS_len == 3)
write_entry(0x102, SHORT_TYPE, 3UL, UL_ BPS_offset);
else
write_entry(0x102, SHORT_TYPE, 1UL, UL_ to.Bits_Per_Sample);
write_entry(0x103, SHORT_TYPE, 1UL, UL_ to.Compression);
write_entry(0x106, SHORT_TYPE, 1UL, UL_ to.Photo_Interp);
write_entry(0x10a, SHORT_TYPE, 1UL, UL_ to.Fill_Order);
write_entry(0x111, LONG_TYPE, UL_ to.Strips, UL_ Strip_Offset);
write_entry(0x115, SHORT_TYPE, 1UL , UL_ to.Samples_Per_Pixel);
write_entry(0x116, LONG_TYPE, 1UL, UL_ to.Rows_Per_Strip);
write_entry(0x117, LONG_TYPE, UL_ to.Strips, UL_ Strips_ByteCount);
write_entry(0x119, SHORT_TYPE,1UL, UL_ to.Max_Sample_Value);
write_entry(0x11a, RATIONAL_TYPE, 1UL, X_Res);
write_entry(0x11b, RATIONAL_TYPE, 1UL, Y_Res);
write_entry(0x11c, SHORT_TYPE, 1UL, UL_ to.Planer_Config);
write_entry(0x128, SHORT_TYPE, 1UL, 2UL);
if( to.Photo_Interp==3 )
write_entry(0x140, SHORT_TYPE, UL_(j*3UL), Color_Map);
write_LONG(0UL,0UL);
return;
TOWNS:
return;
}
/*
画像データを複数ブロックに分ける必要が出たため。
ブロック化をと圧縮(関数呼びだし)をサポートする。
data=256: バッファーのフラッシュ
*/
void write_Gdata(unsigned short data)
{
unsigned static char *add, *pc;
unsigned static long stack_bytes=0; /* RAM内にためてあるバイト数 */
unsigned static long put_bytes=0;
static int INIT=0;
unsigned static long strip_size, strip_offset;
if(INIT == 0){
strip_size=to.Image_Width * to.Rows_Per_Strip * (to.Bits_Per_Sample/8);
if(to.Compression == 1) pc=add=MALLOC( TEMP_SIZE );
else pc=add=MALLOC( strip_size );
strip_offset=ftell(to.fp);
INIT=1;
}
/* 1ストライプのデータが埋まった or データ終了時の処理 */
if( (put_bytes>=strip_size) || (data==256) ){
if( stack_bytes == 0 ) return; /* 出力するデータがないとき */
printf("\r\t\t\t\t\t\t\rLine %3d : ",(to.Strips+1)*(to.Rows_Per_Strip) );
*(to.Strip_Offset + to.Strips) = strip_offset;
if( to.Compression == 5){
compress(add, stack_bytes);
}
else{
fwrite(add, stack_bytes, 1, to.fp);
stack_bytes = ftell( to.fp ) - strip_offset;
printf("Write %lu bytes\n",stack_bytes);
*(to.Strips_ByteCount + to.Strips) = stack_bytes;
}
to.Strips++;
strip_offset = ftell(to.fp);
pc=add;
stack_bytes = put_bytes = 0;
if( data==256 ){
free(add);
INIT=0;
return;
};
};
/* RAM内にためてあるデータが、一定量(TEMP_SIZE)を越して、出力するとき */
if( (to.Compression==1) && (stack_bytes==TEMP_SIZE) ){
printf("\rWrite %lu bytes(%d%)\t\t\t\t\t\r",TEMP_SIZE,100*put_bytes/strip_size);
fwrite(add, TEMP_SIZE, 1, to.fp);
stack_bytes = 0;
pc = add;
}
*pc=data; /* コンパイラーによって違う処理をするそうです */
pc++;
stack_bytes++;
put_bytes ++;
return;
}